#include "global.h"
#include "RageLog.h"
#include "RageThreads.h"
#include "ArchHooks_Wii.h"
#include "StepMania.h"
#include "archutils/Wii/SignalHandler.h"
#include "archutils/Wii/GetSysInfo.h"
#include "archutils/Wii/EmergencyShutdown.h"
#include "RageUtil.h"
#include <sys/time.h>
#include <ogcsys.h>
#include <fat.h>
#include <wiiuse/wpad.h>

#if defined(CRASH_HANDLER)
#include "archutils/Wii/CrashHandler.h"
#endif

static u32 *xfb;
static GXRModeObj *rmode;

static void InitFilesystem();

ArchHooks_Wii::ArchHooks_Wii()
{
	VIDEO_Init();
	WPAD_Init();
	
	rmode = VIDEO_GetPreferredMode(NULL);
	xfb = (u32*)MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
	
	// set up the console
	console_init(xfb, 20, 20, rmode->fbWidth, rmode->xfbHeight, rmode->fbWidth * VI_DISPLAY_PIX_SZ);
	
	VIDEO_Configure(rmode);
	VIDEO_SetNextFramebuffer(xfb);
	VIDEO_SetBlack(FALSE);
	VIDEO_Flush();
	VIDEO_WaitVSync();
	if(rmode->viTVMode & VI_NON_INTERLACE) 
		VIDEO_WaitVSync();
	
	printf("Video initialized!\n");
	
	InitFilesystem();
	
	printf("Filesystem initialized!\n");
	
	for(int i = 0; i < g_argc; i++)
		printf("Arg %d: %s\n", i, g_argv[i]);
		
	while(0) {

		// Call WPAD_ScanPads each loop, this reads the latest controller states
		WPAD_ScanPads();

		// WPAD_ButtonsDown tells us which buttons were pressed in this loop
		// this is a "one shot" state which will not fire again until the button has been released
		u32 pressed = WPAD_ButtonsDown(0);

		// We return to the launcher application via exit
		if ( pressed & WPAD_BUTTON_HOME ) exit(0);

		// Wait for the next frame
		VIDEO_WaitVSync();
	}
	
	
	/* First, handle non-fatal termination signals. */
	//SignalHandler::OnClose( DoCleanShutdown );

#if defined(CRASH_HANDLER)
	//CrashHandlerHandleArgs( g_argc, g_argv );
	//InitializeCrashHandler();
	//SignalHandler::OnClose( DoCrashSignalHandler );
#endif

	/* Set up EmergencyShutdown, to try to shut down the window if we crash.
	 * This might blow up, so be sure to do it after the crash handler. */
	//SignalHandler::OnClose( EmergencyShutdown );

#if defined(HAVE_TLS)
	//TestTLS();
#endif
}

ArchHooks_Wii::~ArchHooks_Wii()
{
	printf("Press HOME to exit...\n");
	
	// Wii debugging code to show the screen
	while(1) {

		// Call WPAD_ScanPads each loop, this reads the latest controller states
		WPAD_ScanPads();

		// WPAD_ButtonsDown tells us which buttons were pressed in this loop
		// this is a "one shot" state which will not fire again until the button has been released
		u32 pressed = WPAD_ButtonsDown(0);

		// We return to the launcher application via exit
		if ( pressed & WPAD_BUTTON_HOME )
		{
			printf("Returning to HBC...\n");
			exit(0);
		}

		// Wait for the next frame
		VIDEO_WaitVSync();
	}
}

static int64_t GetMicrosecondsSinceEpoch()
{
	struct timeval tv;
	gettimeofday( &tv, NULL );

	return int64_t(tv.tv_sec) * 1000000 + int64_t(tv.tv_usec);
}

int64_t ArchHooks::GetMicrosecondsSinceStart( bool bAccurate )
{
	static int64_t iStartTime = GetMicrosecondsSinceEpoch();
	int64_t ret = GetMicrosecondsSinceEpoch() - iStartTime;
	if( bAccurate )
		ret = FixupTimeIfBackwards( ret );
	return ret;
}

static void InitFilesystem() 
{
	if (!fatInitDefault()) 
		printf("Unable to initialise FAT subsystem, exiting.\n");
	if (chdir("SD:/")) 
		printf("Could not change to root directory, exiting.\n");
}


// todo: need to do this somewhere
//	fatUnmount(0);

/*
 * (c) 2003-2004 Glenn Maynard, Eric Borbely
 * All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, and/or sell copies of the Software, and to permit persons to
 * whom the Software is furnished to do so, provided that the above
 * copyright notice(s) and this permission notice appear in all copies of
 * the Software and that both the above copyright notice(s) and this
 * permission notice appear in supporting documentation.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
 * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
 * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
 * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */
